#include "preHeader.h"
#include "PacketDispatcher.h"
#include "MapServer.h"
#include "Cross/CrossServer.h"

enum PacketDispatcherProtocol
{
	CPDP_NONE,
	CPDP_RPC_INVOKE_2_CROSS_SERVER,
	CPDP_RPC_INVOKE_2_MAP_SERVER,
	CPDP_RPC_REPLY,
};

PacketDispatcher::PacketDispatcher()
{
	RPCActor::SetReady(true);
}

PacketDispatcher::~PacketDispatcher()
{
}

void PacketDispatcher::Tick()
{
	mgr_.TickObjs();
}

void PacketDispatcher::SendPacket2CrossServer(uint32 opcode, const std::string_view& data)
{
	auto pck = INetPacket::New(opcode, data.size());
	pck->Append(data.data(), data.size());
	sCrossServer.GetService()->PushRecvPacket(pck);
}

void PacketDispatcher::SendPacket2CrossServer(const INetPacket &pck)
{
	sCrossServer.GetService()->PushRecvPacket(pck.Clone());
}

void PacketDispatcher::SendPacket2Mapserver(const INetPacket &pck)
{
	sMapServer.GetService()->PushRecvPacket(pck.Clone());
}

uint64 PacketDispatcher::RPCInvoke2CrossServer(const INetPacket &pck,
	const std::function<void(INetStream&, int32, bool)> &cb,
	AsyncTaskOwner *owner, time_t timeout)
{
	NetPacket trans(CPDP_RPC_INVOKE_2_CROSS_SERVER);
	return RPCTransInvoke(trans, pck, cb, owner, timeout);
}

uint64 PacketDispatcher::RPCInvoke2Mapserver(const INetPacket &pck,
	const std::function<void(INetStream&, int32, bool)> &cb,
	AsyncTaskOwner *owner, time_t timeout)
{
	NetPacket trans(CPDP_RPC_INVOKE_2_MAP_SERVER);
	return RPCTransInvoke(trans, pck, cb, owner, timeout);
}

void PacketDispatcher::RPCReply(
	const INetPacket &pck, uint64 sn, int32 err, bool eof)
{
	NetPacket trans(CPDP_RPC_REPLY);
	RPCTransReply(trans, pck, sn, err, eof);
}

void PacketDispatcher::PushRPCPacket(const INetPacket &trans,
	const INetPacket &pck, const std::string_view &args)
{
	INetPacket* pkt = pck.Clone();
	pkt->Append(args.data(), args.size());
	switch (trans.GetOpcode()) {
	case CPDP_RPC_INVOKE_2_CROSS_SERVER:
		sCrossServer.GetService()->PushRecvPacket(pkt);
		break;
	case CPDP_RPC_INVOKE_2_MAP_SERVER:
		sMapServer.GetService()->PushRecvPacket(pkt);
		break;
	case CPDP_RPC_REPLY:
		mgr_.OnRPCReply(pkt);
		break;
	default:
		assert(false && "can't reach here.");
		delete pkt;
		break;
	}
}
